<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>数字人WebSocket测试</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
            background-color: #f5f5f5;
        }
        .container {
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        .section {
            margin-bottom: 30px;
            padding: 20px;
            border: 1px solid #ddd;
            border-radius: 5px;
        }
        .section h3 {
            margin-top: 0;
            color: #333;
        }
        .form-group {
            margin-bottom: 15px;
        }
        label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
        }
        input[type="text"], input[type="url"] {
            width: 100%;
            padding: 8px;
            border: 1px solid #ddd;
            border-radius: 4px;
            box-sizing: border-box;
        }
        button {
            background-color: #007bff;
            color: white;
            padding: 10px 20px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            margin-right: 10px;
            margin-bottom: 10px;
        }
        button:hover {
            background-color: #0056b3;
        }
        button:disabled {
            background-color: #6c757d;
            cursor: not-allowed;
        }
        .status {
            padding: 10px;
            border-radius: 4px;
            margin-bottom: 15px;
        }
        .status.connected {
            background-color: #d4edda;
            color: #155724;
            border: 1px solid #c3e6cb;
        }
        .status.disconnected {
            background-color: #f8d7da;
            color: #721c24;
            border: 1px solid #f5c6cb;
        }
        .status.connecting {
            background-color: #fff3cd;
            color: #856404;
            border: 1px solid #ffeaa7;
        }
        .log-container {
            background-color: #f8f9fa;
            border: 1px solid #dee2e6;
            border-radius: 4px;
            padding: 15px;
            height: 400px;
            overflow-y: auto;
            font-family: 'Courier New', monospace;
            font-size: 12px;
        }
        .log-entry {
            margin-bottom: 5px;
            padding: 2px 0;
        }
        .log-entry.info {
            color: #007bff;
        }
        .log-entry.success {
            color: #28a745;
        }
        .log-entry.error {
            color: #dc3545;
        }
        .log-entry.warning {
            color: #ffc107;
        }
        .log-entry.event {
            color: #6f42c1;
            font-weight: bold;
        }
        .clear-btn {
            background-color: #6c757d;
        }
        .clear-btn:hover {
            background-color: #545b62;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>数字人WebSocket测试页面</h1>
        
        <!-- 连接配置 -->
        <div class="section">
            <h3>连接配置</h3>
            <div class="form-group">
                <label for="baseUrl">WebSocket基础URL:</label>
                <input type="url" id="baseUrl" value="ws://localhost:8080" placeholder="例如: ws://localhost:8080">
            </div>
            <div class="form-group">
                <label for="token">认证Token:</label>
                <input type="text" id="token" placeholder="输入认证token">
            </div>
            <button id="connectBtn" onclick="connectWebSocket()">连接WebSocket</button>
            <button id="disconnectBtn" onclick="disconnectWebSocket()" disabled>断开连接</button>
        </div>

        <!-- 连接状态 -->
        <div class="section">
            <h3>连接状态</h3>
            <div id="statusDisplay" class="status disconnected">
                未连接
            </div>
            <div>
                <strong>心跳状态:</strong> <span id="heartbeatStatus">未启动</span>
            </div>
            <div>
                <strong>重连次数:</strong> <span id="reconnectCount">0</span>
            </div>
        </div>

        <!-- 事件处理 -->
        <div class="section">
            <h3>事件处理</h3>
            <p>当前支持的事件:</p>
            <ul>
                <li><strong>AddCustomVoiceSuccess</strong> - 定制声音创建成功</li>
                <li><strong>AddCustomVoiceFail</strong> - 定制声音创建失败</li>
                <li><strong>AddCustomDpSuccess</strong> - 定制数字人创建成功</li>
                <li><strong>AddCustomDpFail</strong> - 定制数字人创建失败</li>
                <li><strong>AddDpVideoSuccess</strong> - 数字人视频创建成功</li>
                <li><strong>AddDpVideoFail</strong> - 数字人视频创建失败</li>
                <li><strong>AddDpVoiceSuccess</strong> - 数字人语音合成成功</li>
                <li><strong>AddDpVoiceFail</strong> - 数字人语音合成失败</li>
            </ul>
            <button onclick="testCustomVoiceSuccess()">模拟定制声音成功事件</button>
            <button onclick="testCustomVoiceFail()">模拟定制声音失败事件</button>
            <button onclick="testCustomDpSuccess()">模拟定制数字人成功事件</button>
            <button onclick="testCustomDpFail()">模拟定制数字人失败事件</button>
            <button onclick="testDpVideoSuccess()">模拟数字人视频成功事件</button>
            <button onclick="testDpVideoFail()">模拟数字人视频失败事件</button>
            <button onclick="testDpVoiceSuccess()">模拟数字人语音合成成功事件</button>
            <button onclick="testDpVoiceFail()">模拟数字人语音合成失败事件</button>
        </div>

        <!-- 日志 -->
        <div class="section">
            <h3>日志输出</h3>
            <button class="clear-btn" onclick="clearLog()">清空日志</button>
            <div id="logContainer" class="log-container"></div>
        </div>
    </div>

    <script src="digital-person-websocket.js"></script>
    <script>
        let wsClient = null;
        let reconnectCount = 0;

        // 日志功能
        function log(message, type = 'info') {
            const logContainer = document.getElementById('logContainer');
            const timestamp = new Date().toLocaleTimeString();
            const logEntry = document.createElement('div');
            logEntry.className = `log-entry ${type}`;
            logEntry.textContent = `[${timestamp}] ${message}`;
            logContainer.appendChild(logEntry);
            logContainer.scrollTop = logContainer.scrollHeight;
        }

        function clearLog() {
            document.getElementById('logContainer').innerHTML = '';
        }

        // 更新状态显示
        function updateStatus(status, message) {
            const statusDisplay = document.getElementById('statusDisplay');
            statusDisplay.className = `status ${status}`;
            statusDisplay.textContent = message;
        }

        // 更新心跳状态
        function updateHeartbeatStatus(status) {
            document.getElementById('heartbeatStatus').textContent = status;
        }

        // 更新重连次数
        function updateReconnectCount(count) {
            reconnectCount = count;
            document.getElementById('reconnectCount').textContent = count;
        }

        // 连接WebSocket
        function connectWebSocket() {
            const baseUrl = document.getElementById('baseUrl').value;
            const token = document.getElementById('token').value;

            if (!baseUrl) {
                alert('请输入WebSocket基础URL');
                return;
            }

            // 转换ws://或wss://协议
            let wsBaseUrl = baseUrl;
            if (baseUrl.startsWith('http://')) {
                wsBaseUrl = baseUrl.replace('http://', 'ws://');
            } else if (baseUrl.startsWith('https://')) {
                wsBaseUrl = baseUrl.replace('https://', 'wss://');
            }

            log(`正在连接到: ${wsBaseUrl}`, 'info');
            updateStatus('connecting', '正在连接...');

            // 创建WebSocket客户端
            wsClient = new DigitalPersonWebSocketClient(wsBaseUrl, token);

            // 注册事件处理器
            wsClient.onEvent('AddCustomVoiceSuccess', (data) => {
                log(`🎉 定制声音创建成功: id=${data.id}, linkId=${data.linkId}`, 'event');
            });

            wsClient.onEvent('AddCustomVoiceFail', (data) => {
                log(`❌ 定制声音创建失败: id=${data.id}, linkId=${data.linkId}, status=${data.status}`, 'event');
            });

            wsClient.onEvent('AddCustomDpSuccess', (data) => {
                log(`🎉 定制数字人创建成功: id=${data.id}, linkId=${data.linkId}`, 'event');
            });

            wsClient.onEvent('AddCustomDpFail', (data) => {
                log(`❌ 定制数字人创建失败: id=${data.id}, linkId=${data.linkId}, status=${data.status}`, 'event');
            });

            wsClient.onEvent('AddDpVideoSuccess', (data) => {
                log(`🎉 数字人视频创建成功: id=${data.id}, linkId=${data.linkId}`, 'event');
            });

            wsClient.onEvent('AddDpVideoFail', (data) => {
                log(`❌ 数字人视频创建失败: id=${data.id}, linkId=${data.linkId}, status=${data.status}`, 'event');
            });

            wsClient.onEvent('AddDpVoiceSuccess', (data) => {
                log(`🎉 数字人语音合成成功: id=${data.id}, linkId=${data.linkId}`, 'event');
            });

            wsClient.onEvent('AddDpVoiceFail', (data) => {
                log(`❌ 数字人语音合成失败: id=${data.id}, linkId=${data.linkId}, status=${data.status}`, 'event');
            });

            // 连接WebSocket
            wsClient.connect(
                // 连接成功回调
                (event) => {
                    log('WebSocket连接成功', 'success');
                    updateStatus('connected', '已连接');
                    updateHeartbeatStatus('运行中 (30秒间隔)');
                    updateReconnectCount(0);
                    
                    document.getElementById('connectBtn').disabled = true;
                    document.getElementById('disconnectBtn').disabled = false;
                },
                // 连接关闭回调
                (event) => {
                    log('WebSocket连接关闭', 'warning');
                    updateStatus('disconnected', '连接已关闭');
                    updateHeartbeatStatus('已停止');
                    
                    document.getElementById('connectBtn').disabled = false;
                    document.getElementById('disconnectBtn').disabled = true;
                },
                // 连接错误回调
                (error) => {
                    log(`WebSocket连接错误: ${error}`, 'error');
                    updateStatus('disconnected', '连接错误');
                    updateHeartbeatStatus('已停止');
                    
                    document.getElementById('connectBtn').disabled = false;
                    document.getElementById('disconnectBtn').disabled = true;
                }
            );
        }

        // 断开WebSocket连接
        function disconnectWebSocket() {
            if (wsClient) {
                wsClient.disconnect();
                wsClient = null;
                log('WebSocket连接已断开', 'info');
                updateStatus('disconnected', '已断开连接');
                updateHeartbeatStatus('已停止');
                
                document.getElementById('connectBtn').disabled = false;
                document.getElementById('disconnectBtn').disabled = true;
            }
        }

        // 模拟定制声音成功事件
        function testCustomVoiceSuccess() {
            if (wsClient && wsClient.getConnectionStatus()) {
                const testData = {
                    event: 'AddCustomVoiceSuccess',
                    data: {
                        id: Math.floor(Math.random() * 1000),
                        linkId: 'test-' + Date.now(),
                        status: 2
                    }
                };
                wsClient.handleMessage(JSON.stringify(testData));
                log('已发送测试事件: AddCustomVoiceSuccess', 'info');
            } else {
                log('WebSocket未连接，无法发送测试事件', 'error');
            }
        }

        // 模拟定制声音失败事件
        function testCustomVoiceFail() {
            if (wsClient && wsClient.getConnectionStatus()) {
                const testData = {
                    event: 'AddCustomVoiceFail',
                    data: {
                        id: Math.floor(Math.random() * 1000),
                        linkId: 'test-' + Date.now(),
                        status: 3
                    }
                };
                wsClient.handleMessage(JSON.stringify(testData));
                log('已发送测试事件: AddCustomVoiceFail', 'info');
            } else {
                log('WebSocket未连接，无法发送测试事件', 'error');
            }
        }

        // 模拟定制数字人成功事件
        function testCustomDpSuccess() {
            if (wsClient && wsClient.getConnectionStatus()) {
                const testData = {
                    event: 'AddCustomDpSuccess',
                    data: {
                        id: Math.floor(Math.random() * 1000),
                        linkId: 'test-' + Date.now(),
                        status: 2
                    }
                };
                wsClient.handleMessage(JSON.stringify(testData));
                log('已发送测试事件: AddCustomDpSuccess', 'info');
            } else {
                log('WebSocket未连接，无法发送测试事件', 'error');
            }
        }

        // 模拟定制数字人失败事件
        function testCustomDpFail() {
            if (wsClient && wsClient.getConnectionStatus()) {
                const testData = {
                    event: 'AddCustomDpFail',
                    data: {
                        id: Math.floor(Math.random() * 1000),
                        linkId: 'test-' + Date.now(),
                        status: 3
                    }
                };
                wsClient.handleMessage(JSON.stringify(testData));
                log('已发送测试事件: AddCustomDpFail', 'info');
            } else {
                log('WebSocket未连接，无法发送测试事件', 'error');
            }
        }

        // 模拟数字人视频成功事件
        function testDpVideoSuccess() {
            if (wsClient && wsClient.getConnectionStatus()) {
                const testData = {
                    event: 'AddDpVideoSuccess',
                    data: {
                        id: Math.floor(Math.random() * 1000),
                        linkId: 'test-' + Date.now(),
                        status: 2
                    }
                };
                wsClient.handleMessage(JSON.stringify(testData));
                log('已发送测试事件: AddDpVideoSuccess', 'info');
            } else {
                log('WebSocket未连接，无法发送测试事件', 'error');
            }
        }

        // 模拟数字人视频失败事件
        function testDpVideoFail() {
            if (wsClient && wsClient.getConnectionStatus()) {
                const testData = {
                    event: 'AddDpVideoFail',
                    data: {
                        id: Math.floor(Math.random() * 1000),
                        linkId: 'test-' + Date.now(),
                        status: 3
                    }
                };
                wsClient.handleMessage(JSON.stringify(testData));
                log('已发送测试事件: AddDpVideoFail', 'info');
            } else {
                log('WebSocket未连接，无法发送测试事件', 'error');
            }
        }

        // 模拟数字人语音合成成功事件
        function testDpVoiceSuccess() {
            if (wsClient && wsClient.getConnectionStatus()) {
                const testData = {
                    event: 'AddDpVoiceSuccess',
                    data: {
                        id: Math.floor(Math.random() * 1000),
                        linkId: 'test-' + Date.now(),
                        status: 2
                    }
                };
                wsClient.handleMessage(JSON.stringify(testData));
                log('已发送测试事件: AddDpVoiceSuccess', 'info');
            } else {
                log('WebSocket未连接，无法发送测试事件', 'error');
            }
        }

        // 模拟数字人语音合成失败事件
        function testDpVoiceFail() {
            if (wsClient && wsClient.getConnectionStatus()) {
                const testData = {
                    event: 'AddDpVoiceFail',
                    data: {
                        id: Math.floor(Math.random() * 1000),
                        linkId: 'test-' + Date.now(),
                        status: 3
                    }
                };
                wsClient.handleMessage(JSON.stringify(testData));
                log('已发送测试事件: AddDpVoiceFail', 'info');
            } else {
                log('WebSocket未连接，无法发送测试事件', 'error');
            }
        }

        // 页面加载完成后的初始化
        document.addEventListener('DOMContentLoaded', function() {
            log('数字人WebSocket测试页面已加载', 'info');
            log('请配置WebSocket URL和Token，然后点击连接按钮', 'info');
        });

        // 页面卸载时断开连接
        window.addEventListener('beforeunload', function() {
            if (wsClient) {
                wsClient.disconnect();
            }
        });
    </script>
</body>
</html> 